/** 
 * \file gdsdot.cu
 * \author Kyle E. Niemeyer
 * \date 10/04/2011
 *
 * Based on "dsdot.f" from BLAS.
 *
 */

////////////////////////////////////////////////////////////////////////

/** gdscal computes a dot product of two real vectors in double precision. BLAS level one.
 *
 * \param[in]   n       number of elements in vector
 * \param[in]   sx      first vector, dimension (n-1) * |incx| + 1
 * \param[in]   incx    increment between elements of sx
 * \param[in]   sy      second vector, dimension (n-1) * |incy| + 1
 * \param[in]   incy    increment between elements of sy
 * \return      dsdot   double precision dot product
 */
__device__ __inline__ double gdsdot ( int n, const float *sx, int incx, const float *sy, int incy )
{
  
  double dsdot = 0.0;
  
  if ( n <= 0 ) return dsdot;
  
  if ( ( incx == incy ) && ( incx > 0 ) ) {
    
    // equal, positive, non-unit increments
    
    uint ns = n * incx;
    for ( uint i = 0; i < ns; i += incx ) {
      dsdot += ( (double) sx[i] ) * ( (double) sy[i] );
    }
    
  } else {
    
    // increment not equal to 1
    
    uint kx = 1;
    uint ky = 1;
    if ( incx < 0 ) kx = 1 + (1 - n) * incx;
    if ( incy < 0 ) ky = 1 + (1 - n) * incy;
    
    for ( uint i = 0; i < n; ++i ) {
      dsdot += ( (double) sx[kx] ) * ( (double) sy[ky] );
      kx += incx;
      ky += incy;
    }
    
  } // end incx if
  
  return dsdot;

} // end gdscal